package com.xxd.rpt3.config;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.xxd.rpt3.Entity.JwtTokenHis;
import com.xxd.rpt3.repository.JwtTokenHisRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import com.xxd.rpt3.service.UserService;
import com.xxd.utils.EHCacheUtils;
import com.xxd.utils.JwtUtil;

@Configuration
public class JwtFilter {

	@Autowired
	UserService userService;

	@Autowired
	JwtTokenHisRepository jwtTokenHisRepository;

	private final String ERROR_URI = "/public/tokenError";

	@Bean
	public FilterRegistrationBean<Filter> filterRegistration() {
		// 新建过滤器注册类
		FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();
		// 添加自定义 过滤器
		registration.setFilter(jwtFilter());
		// 设置过滤器的URL模式
		registration.addUrlPatterns("/*");
		// 设置过滤器顺序
		registration.setOrder(1);
		return registration;
	}

	public Filter jwtFilter() {
		Filter filter = new Filter() {
			@Override
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				HttpServletRequest httpRequest = (HttpServletRequest) request;
				HttpServletResponse httpResponse = (HttpServletResponse) response;
				String requestURI = httpRequest.getRequestURI();
				String token = httpRequest.getHeader(JwtUtil.TOKEN_NAME);
				boolean pubFlag = publicURI(requestURI);
				// 判断，如果请求信息中午token，则取请求参数中token
				if (StringUtils.isEmpty(token)) {
					token = httpRequest.getParameter(JwtUtil.TOKEN_NAME);
				}
				httpRequest.setAttribute(JwtUtil.TOKEN_NAME,token);
				if (pubFlag) {
					chain.doFilter(httpRequest, httpResponse);
				} else {
					// 如果token为空或者失效，则截断请求
					if (StringUtils.isEmpty(token)) {
						httpResponse.sendRedirect(ERROR_URI);
					} else {
						try {
							//先从缓存取
							Object cache =  EHCacheUtils.getTokenCache(token);
							if (cache == null) {// 缓存中没有，则从数据库中取,并刷新缓存
								JwtTokenHis jwtTokenHis = jwtTokenHisRepository.findJwtTokenHisByKey(token);
								if(jwtTokenHis != null){
									pubFlag = JwtUtil.verify(jwtTokenHis.getValue(),jwtTokenHis.getUserCode(),jwtTokenHis.getSalt());
									if(!pubFlag){
										userService.logout(token);
										httpResponse.sendRedirect(ERROR_URI);
									}else {
										JwtUtil.freshToken(jwtTokenHis,jwtTokenHisRepository);
									}
								}else{
									httpResponse.sendRedirect(ERROR_URI);
								}
							}else {
								if( cache.getClass().getName().equals(JwtTokenHis.class.getName()) ){//缓存不为空
									JwtTokenHis jwtTokenHis = (JwtTokenHis) cache;
									pubFlag = JwtUtil.verify(jwtTokenHis.getValue(),jwtTokenHis.getUserCode(),jwtTokenHis.getSalt());
									if(!pubFlag){
										userService.logout(token);
										httpResponse.sendRedirect(ERROR_URI);
									}else{
										JwtUtil.freshToken(jwtTokenHis,jwtTokenHisRepository);
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
							httpResponse.sendRedirect(ERROR_URI);
						}
						chain.doFilter(httpRequest, httpResponse);
					}
				}
			}
		};
		return filter;
	}

	/**
	 *@author: xuxd
	 *@description: 判定请求的url是否是公共请求
	 *@params: ***
	 */

	public boolean publicURI(String requestURI){
		boolean pubFlag = false;
		List<String> notInclude = new ArrayList<>();
		notInclude.add("public");
		notInclude.add("share");
		notInclude.add("druid");
		notInclude.add("static");
		for (String uri : notInclude) {
			if (requestURI.contains(uri)) {
				pubFlag = true;
				break;
			}
		}
		return pubFlag;
	}

}